/* 拓扑排序
* 1.概念:
    首先遍历所有点，将入度为零的点加入队列，然后依次遍历出队的点的所有临边，并将临点的入度-1，若为0则加入队列。
    最终队列中的顺序就是拓扑排序的顺序

* 本题: 
    反向拓扑 边起点要比边终点多到达一个点
*/

#pragma GCC optimize("O1,O2,O3,Ofast")
#pragma GCC optimize("no-stack-protector,unroll-loops,fast-math,inline")
#pragma GCC target("avx,avx2,fma")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,ssse3")

#include <iostream>
#include <cstring>
#include <algorithm> 
#include <queue>
#include <bitset>
// #define ONLINE_GUDGE
using namespace std;
const int N = 30010, M = 30010;

int n, m;
int h[N], hs[N], e[M], ne[M], idx;
queue<int> q;
int d[N];
bitset<N> ans[N];

void AddEdge(int a, int b) // , int c)
{ e[idx] = b, ne[idx] = h[a], h[a] = idx ++;} // w[idx] = c, 

void TopSort()
{
    for(int u = 1; u <= n; u++){
        ans[u][u] = 1; // 本身可达
        if(!d[u]) q.push(u); // 初始化
    }
        
    while(q.size())
    {
        auto u = q.front(); q.pop();
        for(int i = h[u]; ~i; i = ne[i]){
            auto v = e[i];
            ans[v] |= ans[u]; // 边原点可以到边终点的所有可达点
            if(--d[v] == 0) q.push(v);
        }
    }
}

int main()
{

    #ifdef ONLINE_JUDGE

    #else
    freopen("./in.txt","r",stdin);
    #endif
    ios::sync_with_stdio(false);   
	cin.tie(0);
    
    cin >> n >> m;
    memset(h, -1, sizeof h);

    while(m--){
        int i ,j; cin >> i >> j;
            AddEdge(j, i); // 反向边反推
            d[i]++;
        
    }

    TopSort();

    for(int i = 1; i <= n; i++)
        cout << ans[i].count() << endl;

    return 0;
}